package com.xyzwps.collections.map

import com.xyzwps.collections.Range

import java.util.function.Supplier

import static org.junit.jupiter.api.Assertions.*

class TestMap {

    def static 'case - put - get - hasKey'(Map<Integer, Integer> map) {
        assertTrue map.isEmpty()
        assertFalse map.isNonEmpty()
        assertEquals map.size(), 0

        final int MAX = 242
        for (int i = 0; i < MAX; i++) {
            assertFalse map.hasKey(i)
            assertEquals map.size(), i

            map.put i, i
            assertTrue map.hasKey(i)
            assertEquals map.get(i), i
            assertEquals map.size(), i + 1

            map.put i, 2 * i
            assertTrue map.hasKey(i)
            assertEquals map.get(i), 2 * i
            assertEquals map.size(), i + 1
        }
    }

    def static 'case - put - get - hasKey operator'(Map<Integer, Integer> map) {
        assertTrue map.isEmpty()
        assertFalse map.isNonEmpty()
        assertEquals map.size(), 0

        final int MAX = 242
        for (int i = 0; i < MAX; i++) {
            assertFalse i in map
            assertEquals map.size(), i

            map[i] = i
            assertTrue i in map
            assertEquals map[i], i
            assertEquals map.size(), i + 1

            map[i] = 2 * i
            assertTrue i in map
            assertEquals map[i], 2 * i
            assertEquals map.size(), i + 1
        }
    }

    def static 'case - null'(Map<Integer, Integer> map) {
        assertTrue map.isEmpty()
        assertFalse map.isNonEmpty()
        assertEquals map.size(), 0

        final int MAX = 553
        for (int i = 0; i < MAX; i++) {
            assertFalse i in map
            assertNull map[i]

            map[i] = i
            assertTrue i in map
            assertEquals map[i], i
            assertEquals map.size(), i + 1

            map[i] = null
            assertTrue i in map
            assertNull map[i]
            assertEquals map.size(), i + 1
        }

        assertFalse null in map
        assertNull map[null]
        map[null] = 12345
        assertTrue null in map
        assertEquals map[null], 12345
    }

    def static 'case - remove'(Map<Integer, Integer> map) {
        assertTrue map.isEmpty()
        assertFalse map.isNonEmpty()
        assertEquals map.size(), 0

        final int COUNT = 323
        for (int i : Range.create(COUNT - 1)) {
            map.put(i, i)
            assertTrue i in map
            assertEquals map.size(), (i + 1)
        }

        for (int i : Range.create(-233, COUNT * 2)) {
            if (i < 0) {
                assertFalse map.remove(i)
                assertEquals map.size(), COUNT
            } else if (i < COUNT) {
                assertTrue map.remove(i)
                assertEquals map.size(), COUNT - 1 - i
                assertFalse i in map
            } else {
                assertFalse map.remove(i)
                assertEquals map.size(), 0
            }
        }

    }

    def static testCommons(Supplier<Map<Integer, Integer>> supplier) {
        "case - put - get - hasKey" supplier.get()
        "case - put - get - hasKey operator" supplier.get()
        "case - null" supplier.get()
        "case - remove" supplier.get()
    }
}
